#include "player.h"
#include "scene.h"


Player::Player(Point initial_position, Model &model, double maxSize)
{
    model_ = (&model);
    model.updateBoundingBox();
    Box box = model.boundingBox();
    float maxAresta = 0;
    float maxArestaX = (box.maxb.x-box.minb.x);
    float maxArestaY = (box.maxb.y-box.minb.y);
    float maxArestaZ = (box.maxb.z-box.minb.z);
    if ((maxArestaX >= maxArestaY) and (maxArestaX >= maxArestaZ)) maxAresta = maxArestaX;
    else if(maxArestaY >= maxArestaZ) maxAresta = maxArestaY;
    else maxAresta = maxArestaZ;
    position_ = initial_position;
    position_.y +=  20;
    angleX_ = 0;
    angleY_ = 0;
    box_ = model_->boundingBox();
    pintaCaixa_ = false;
    moviment_ = maxSize/2;
    escala_ = maxSize/maxAresta;
    Vector diagonal = box.maxb - box.minb;
    diagonal_ = diagonal.length()*escala_;
}

void Player::Render(){
    if(model_!=NULL){

        cameraIDI camAux;
        camAux.iniciTGModelat();
        camAux.trasllada(position_.x, position_.y, position_.z);
        camAux.rota(angleY_, 0,1.0,0);
        camAux.rota(angleX_, 1.0,0,0);
        camAux.rota(-90,1.0, 0, 0); //posa el dofi en l'orientació desitjada

        camAux.escala(escala_, escala_, escala_);

        //Pintem l'objecte


        model_->Render();
        //Box box = model_->boundingBox();
        //box.Render();


        camAux.fiTGModelat();


    }
}

void Player::giraDreta() {
    angleY_ -= ANGLE_ROTACIO;
    model_->updateBoundingBox();
    box_ = model_->boundingBox();
}

void Player::giraEsquerra() {
    angleY_ += ANGLE_ROTACIO;
    model_->updateBoundingBox();
    box_ = model_->boundingBox();
}

void Player::amunt(){
     angleX_ += ANGLE_ROTACIO;
     if (angleX_ > 89.99) angleX_ = 89.99;
     model_->updateBoundingBox();
     box_ = model_->boundingBox();
}

void Player::abaix(){

     angleX_ -= ANGLE_ROTACIO;
     if (angleX_ < -89.99) angleX_ = -89.99;
     model_->updateBoundingBox();
     box_ = model_->boundingBox();
}

Point Player::endavant(){
    Point position;
    float distanciaY = moviment_ * sin(angleX_*PI/180);
    position.y = position_.y + distanciaY;
    float distanciaPlaXZ = moviment_ * cos(angleX_*PI/180);
    float distanciaX = distanciaPlaXZ * sin(angleY_*PI/180);
    distanciaX *= -1;
    position.x = position_.x + distanciaX;
    float distanciaZ = distanciaPlaXZ * cos(angleY_*PI/180);
    distanciaZ *= -1;
    position.z = position_.z + distanciaZ;
    return position;
}

void Player::pintaCaixa(){
    pintaCaixa_ = true;
}

void Player::move(Point position){
    position_ = position;
}

float Player::getDiagonal(){
    return diagonal_;
}

void Player::pintaEsfera(){
    cameraIDI camAux;

    camAux.iniciTGModelat();
    camAux.trasllada(position_.x, position_.y, position_.z);

    glLineWidth( 1.0 );
    glMaterialfv(GL_FRONT, GL_DIFFUSE, (GLfloat[]) {0.3, 0.4, 1});
    glColor3f(0.3, 0.4, 1);

    glBegin( GL_LINE_LOOP );
    GLUquadricObj *quadric;
    quadric = gluNewQuadric();

    gluQuadricDrawStyle(quadric, GLU_FILL );
    gluSphere( quadric , diagonal_/2 , 36 , 36);

    gluDeleteQuadric(quadric);

    camAux.fiTGModelat();
}


void Player::encenLot(){
    GLfloat ambient[] = { 0.10, 0.10, 0, 1.0 };
    Point positionLot = getPuntDeVista();
    GLfloat position[] = { positionLot.x, positionLot.y, positionLot.z , 1.0 };
    GLfloat diffuse[] = { 0.5, 0.5, 0, 0.5};
    Vector vdirection = endavant() - position_;
    vdirection.normalize();
    GLfloat direction[] = { vdirection.x, vdirection.y, vdirection.z };
    float angle = 20;
    glLightfv(GL_LIGHT2, GL_AMBIENT, ambient);
    glLightfv(GL_LIGHT2, GL_DIFFUSE, diffuse);
    glLightfv(GL_LIGHT2, GL_POSITION, position);
    glLightfv(GL_LIGHT2, GL_SPOT_DIRECTION, direction);
    glLightf(GL_LIGHT2, GL_SPOT_CUTOFF, angle);
}

Point Player::getPuntDeVista(){
    Point position;
    float distanciaY = diagonal_/2 * sin(angleX_*PI/180);
    position.y = position_.y + distanciaY;
    float distanciaPlaXZ = diagonal_/2 * cos(angleX_*PI/180);
    float distanciaX = distanciaPlaXZ * sin(angleY_*PI/180);
    distanciaX *= -1;
    position.x = position_.x + distanciaX;
    float distanciaZ = distanciaPlaXZ * cos(angleY_*PI/180);
    distanciaZ *= -1;
    position.z = position_.z + distanciaZ;
    return position;
}

Point Player::getPuntDistant(float distancia){
    Point position;
    float distanciaY = distancia * sin(angleX_*PI/180);
    position.y = position_.y + distanciaY;
    float distanciaPlaXZ = distancia * cos(angleX_*PI/180);
    float distanciaX = distanciaPlaXZ * sin(angleY_*PI/180);
    distanciaX *= -1;
    position.x = position_.x + distanciaX;
    float distanciaZ = distanciaPlaXZ * cos(angleY_*PI/180);
    distanciaZ *= -1;
    position.z = position_.z + distanciaZ;
    return position;
}

void Player::primeraPersona(){
    glMatrixMode(GL_MODELVIEW); //Modifiquem matriu ModelView (Camera)
    glLoadIdentity(); //Coloquem camera a l'origent (punt per defecte)
    Point puntDeVista = getPuntDistant(50);
    Point VRP = endavant();
    gluLookAt(  VRP.x, VRP.y, VRP.z, puntDeVista.x, puntDeVista.y, puntDeVista.z, 0, 1, 0);
}

